package org.smile.commons;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
 * 解析xml文件类
 * @author strive
 *
 */
public class XmlParser {
	
	/**
	 * 解析一个结点的所有属性成一个map 
	 * 只包括当前结点 不包括其子结点
	 * @param node
	 * @return
	 */
	public Map<String,String> parseNodeAttribute(Node node){
		Map map=new HashMap();
		NamedNodeMap childs=node.getAttributes();
		if(childs!=null){
			for(int i=0;i<childs.getLength();i++){
				Node temp=childs.item(i);
				map.put(temp.getNodeName(), temp.getNodeValue());
			}
		}
		return map;
	}
	
	
	public Map<String,Object> parseXMLFile(InputStream is){
		try {
			Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
			return this.parseNode(doc);
		} catch (Exception e) {
			e.printStackTrace();
		} 
		return null;
	
	}
	/**
	 * 解析一个xml节点成一个Map
	 * @param node
	 * @return
	 */
	public Map<String,Object> parseNode(Node node){
		return (Map)this.parseXmlNode(node);
	}
	/**
	 * 解析一个xml的节点 包括其所有的子结节
	 * @param node
	 * @return 
	 */
    public  Object parseXmlNode(Node node){
    	short type=node.getNodeType();
    	if(type==3){
    		//为文本的时候
    		return node.getNodeValue().trim();
    	}else{
    		//不为文本是一个结点
    		Map map=parseNodeAttribute(node);
    		NodeList nodes=node.getChildNodes();
    		if(map.isEmpty()&&!this.hasNodeChild(nodes)){
    			return getNodeText(nodes);
    		}else if(!map.isEmpty()&&!this.hasNodeChild(nodes)){
    			String value= getNodeText(nodes);
    			if(value!=null&&!"".equals(value.trim())){
    				putMap(map,"value", value);
    			}
    			return map;
    		}else{
    			for(int i=0;i<nodes.getLength();i++){
    				Node n=nodes.item(i);
    				Object value=parseXmlNode(n);
    				short _type=n.getNodeType();
    				if(_type!=3){
	    				putMap(map,n.getNodeName(), value);
    				}
    			}
    			return map;
    		}
    		
    	}
    }
    /**
     * 往map里填数据 如当前map中的已经存在key 
     * 则把key对应的对象转成List 并把样同key的对象放到list中
     * @param map
     * @param key
     * @param v
     */
    private  void putMap(Map map ,Object key,Object v){
    	if(map.containsKey(key)){
    		Object value=map.get(key);
    		if(value instanceof List){
    			List list=(List)map.get(key);
    			list.add(v);
    		}else{
    			List list=new ArrayList();
    			list.add(map.get(key));
    			list.add(v);
    			map.put(key, list);
    		}
    		
    	}else{
    		map.put(key, v);
    	}
    }  
    /**
     * 是否有非文本子节点
     * @param nodes
     * @return
     */
    private boolean hasNodeChild(NodeList nodes){
    	if(nodes.getLength()==0){
    		return false;
    	}else if(nodes.getLength()==1){
    		if(nodes.item(0).getNodeType()==3){
    			return false;
    		}else{
        		return true;
        	}
    	}else{
    		return true;
    	}
    }
    /**
     * 得到文本结点的文本 已经确定只有文本结点
     * @param nodes
     * @return
     */
    private String getNodeText(NodeList nodes){
    	if(nodes.getLength()==1){
    		return nodes.item(0).getNodeValue().trim();
    	}
    	return "";
    }
}
